class Point
  attr_accessor :x, :y, :z
  
  def initialize(x=0, y=0, z=0)
    @x = x.to_f
    @y = y.to_f
    @z = z.to_f
  end
  
  def +(object)
    return Point.new(@x + object.x, @y + object.y, @z + object.z) if object.is_a? Point
    Point.new @x - object, @y - object, @z - object
  end
  
  def -(object)
    return Point.new(@x - object.x, @y - object.y, @z - object.z) if object.is_a? Point
    Point.new @x - object, @y - object, @z - object
  end
  
  def *(number)
    Point.new @x * number, @y * number, @z * number
  end
  
  def /(number)
    Point.new @x / number, @y / number, @z / number
  end
  
  def distance_to(point)
    (self - point).length
  end
  
  def dot(point)
    @x * point.x + @y * point.y + @z * point.z
  end
  
  def length
    Math.sqrt(length_squared)
  end
  
  def length_squared
    dot self
  end
  
  def normalize
    l = length
    return Point.new(1, 0, 0) if l == 0
    self / length
  end
  
  def normalize!
    n = normalize
    @x = n.x
    @y = n.y
    @z = n.z
  end
  
  def zero?
    @x == 0 and @y == 0 and @z == 0
  end
end